package com.dustedpixels.soot;

import static org.objectweb.asm.Opcodes.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import org.apache.commons.io.IOUtils;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.ASMifierClassVisitor;


/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class SootTest {
  public static void main(String[] args) throws Exception {
    //generate("Nand.class");
    //asmify("Nand.class");
    asmify("sootOutput/Nand.class");
  }
  
  static void generate(String filename) throws Exception {
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    
    writer.visit(
        V1_5, 
        ACC_FINAL | ACC_PUBLIC,
        "Nand",
        null,
        "java/lang/Object",
        new String[] {});
    
    MethodVisitor methodWriter = writer.visitMethod(
        ACC_PUBLIC, 
        "run",
        "(II)I",
        null,
        null);
    
    methodWriter.visitCode();
    methodWriter.visitIntInsn(ALOAD, 0);
    methodWriter.visitIntInsn(ALOAD, 0);
    methodWriter.visitIntInsn(ILOAD, 1);
    methodWriter.visitIntInsn(ILOAD, 2);
    methodWriter.visitIntInsn(ISTORE, 5);
    methodWriter.visitIntInsn(ISTORE, 4);
    methodWriter.visitIntInsn(ASTORE, 3);
    methodWriter.visitIntInsn(ILOAD, 4);
    methodWriter.visitIntInsn(ILOAD, 5);
    methodWriter.visitInsn(IAND);
    methodWriter.visitIntInsn(ISTORE, 4);
    methodWriter.visitIntInsn(ASTORE, 3);
    methodWriter.visitIntInsn(ILOAD, 4);
    methodWriter.visitInsn(INEG);
    methodWriter.visitInsn(IRETURN);
    
    methodWriter.visitMaxs(0, 0);
    methodWriter.visitEnd();
    
    writer.visitEnd();
   
    OutputStream output = new FileOutputStream(filename);
    try {
      IOUtils.write(writer.toByteArray(), output);
    } finally {
      output.close();
    }
  }
  
  static void asmify(String filename) throws Exception {
    InputStream input = new FileInputStream(filename);
    try {
      ClassReader reader = new ClassReader(input);
      ClassVisitor asmifier = new ASMifierClassVisitor(new PrintWriter(System.out));
      reader.accept(asmifier, 0);
    } finally {
      input.close();
    }
  }
}
